package com.newjiabo.ski.service.impl;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.newjiabo.common.core.enums.ResultCode;
import com.newjiabo.common.exception.ServiceException;
import com.newjiabo.common.ski.media.utils.WxPayUtil;
import com.newjiabo.common.utils.DateUtils;
import com.newjiabo.common.utils.SnowFlake;
import com.newjiabo.common.utils.StringUtils;
import com.newjiabo.ski.domain.SkiOrder;
import com.newjiabo.ski.domain.enums.AfterSaleEnum;
import com.newjiabo.ski.domain.vo.AfterSaleInfoVo;
import com.newjiabo.ski.domain.vo.OrderDetailInfoVo;
import com.newjiabo.ski.service.ISkiOrderService;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.newjiabo.ski.mapper.SkiAfterSaleMapper;
import com.newjiabo.ski.domain.SkiAfterSale;
import com.newjiabo.ski.service.ISkiAfterSaleService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 售后Service业务层处理
 *
 * @author CaoMengHui
 * @date 2023-09-23
 */
@Service
public class SkiAfterSaleServiceImpl implements ISkiAfterSaleService {
    @Resource
    private SkiAfterSaleMapper skiAfterSaleMapper;
    @Resource
    private WxPayUtil wxPayUtil;
    @Resource
    private ISkiOrderService orderService;

    private static final Logger log = LoggerFactory.getLogger(SkiAfterSaleServiceImpl.class);

    /**
     * 查询售后
     *
     * @param id 售后主键
     * @return 售后
     */
    @Override
    public SkiAfterSale selectSkiAfterSaleById(String id) {
        return skiAfterSaleMapper.selectSkiAfterSaleById(id);
    }

    /**
     * 查询售后列表
     *
     * @param skiAfterSale 售后
     * @return 售后
     */
    @Override
    public List<SkiAfterSale> selectSkiAfterSaleList(SkiAfterSale skiAfterSale) {
        return skiAfterSaleMapper.selectSkiAfterSaleList(skiAfterSale);
    }

    /**
     * 新增售后
     *
     * @param skiAfterSale 售后
     * @return 结果
     */
    @Override
    public int insertSkiAfterSale(SkiAfterSale skiAfterSale) {
        if (StringUtils.isEmpty(skiAfterSale.getId())) {
            skiAfterSale.setId(SnowFlake.getIdStr());
        }
        skiAfterSale.setDeleteFlag(false);
        skiAfterSale.setCreateTime(DateUtils.getNowDate());
        return skiAfterSaleMapper.insertSkiAfterSale(skiAfterSale);
    }

    /**
     * 修改售后
     *
     * @param skiAfterSale 售后
     * @return 结果
     */
    @Override
    public int updateSkiAfterSale(SkiAfterSale skiAfterSale) {
        skiAfterSale.setUpdateTime(DateUtils.getNowDate());
        return skiAfterSaleMapper.updateSkiAfterSale(skiAfterSale);
    }

    /**
     * 批量删除售后
     *
     * @param ids 需要删除的售后主键
     * @return 结果
     */
    @Override
    public int deleteSkiAfterSaleByIds(String[] ids) {
        return skiAfterSaleMapper.deleteSkiAfterSaleByIds(ids);
    }

    /**
     * 删除售后信息
     *
     * @param id 售后主键
     * @return 结果
     */
    @Override
    public int deleteSkiAfterSaleById(String id) {
        return skiAfterSaleMapper.deleteSkiAfterSaleById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int processAfter(String afterSaleId, Double actualRefundPrice, String auditRemark, String serviceStatus) {
        SkiAfterSale skiAfterSale = this.selectSkiAfterSaleById(afterSaleId);
        skiAfterSale.setActualRefundPrice(actualRefundPrice);
        skiAfterSale.setAuditRemark(auditRemark);
        skiAfterSale.setServiceStatus(serviceStatus);
        if (ObjectUtil.isNull(skiAfterSale)) {
            throw new ServiceException(ResultCode.AFTER_SALES_ORDER_ERROR);
        }
        switch (AfterSaleEnum.valueOf(serviceStatus)) {
            case agreeRefund:
                if (skiAfterSale.getFlowPrice() < actualRefundPrice) {
                    throw new ServiceException(ResultCode.AFTER_SALES_AMOUNT_ERROR);
                }
                SkiOrder skiOrder = orderService.selectSkiOrderByOrderId(skiAfterSale.getOrderId());
                domesticRefunds(skiOrder.getPayNo(),skiAfterSale.getOutRefundNo(),actualRefundPrice,skiOrder.getTotal(),skiAfterSale);
                skiAfterSale.setActualRefundPrice(actualRefundPrice);
                break;
            case refuseRefund:
                this.updateSkiAfterSale(skiAfterSale);
                break;
            default:
                throw new ServiceException(ResultCode.AFTER_SALES_STATUS_ERROR);
        }
        skiAfterSale.setAuditRemark(auditRemark);
        return this.updateSkiAfterSale(skiAfterSale);
    }

    @Override
    public SkiAfterSale selectByOrder(String refundId, String outRefundNoResult, String outTradeNo) {
        return skiAfterSaleMapper.selectByOrders(refundId, outRefundNoResult, outTradeNo);
    }

    @Override
    public AfterSaleInfoVo getInfo(String id) {
        SkiAfterSale afterSale = this.selectSkiAfterSaleById(id);
        OrderDetailInfoVo infoDetail = orderService.getInfoDetail(afterSale.getOrderId());
        return new AfterSaleInfoVo(afterSale,infoDetail);
    }

    /**
     * 退款处理
     *
     * @param transactionId 微信支付订单号
     * @param outRefundNo   商户退款单号
     * @param refund        退款金额
     * @param total         原订单金额
     * @return
     * @throws Exception
     */
    public void domesticRefunds(String transactionId, String outRefundNo, Double refund, Double total,SkiAfterSale afterSale) {
        CloseableHttpResponse refundInfo = null;
        try {
            refundInfo = wxPayUtil.getRefundInfo(transactionId, outRefundNo, refund, total);
            int statusCode = refundInfo.getStatusLine().getStatusCode();
            log.info("申请退款状态为：{}", statusCode);
            String orderStr = EntityUtils.toString(refundInfo.getEntity(), StandardCharsets.UTF_8);
            log.info("申请退款参数为：{}", orderStr);
            if (statusCode == 200) {
                JSONObject refundInfoObj = JSONObject.parseObject(orderStr);
                // 【微信支付退款号】 微信支付退款号
                String refundId = refundInfoObj.getString("refund_id");
                // 商户退款单号
                String outRefundNoResult = refundInfoObj.getString("out_refund_no");
                // 微信支付订单号
                String transactionIdResult = refundInfoObj.getString("transaction_id");
                // 商户订单号
                String outTradeNo = refundInfoObj.getString("out_trade_no");
                //【退款渠道】 退款渠道
                String channel = refundInfoObj.getString("channel");
                // 退款入账账户
                String userReceivedAccount = refundInfoObj.getString("user_received_account");
                // 退款创建时间
                String createTime = refundInfoObj.getString("create_time");
                // 退款状态
                String status = refundInfoObj.getString("status");

                if (ObjectUtil.isNull(afterSale)) {
                    throw new ServiceException(ResultCode.AFTER_SALES_ORDER_ERROR);
                }
                afterSale.setRefundWay(channel);
                afterSale.setUserReceivedAccount(userReceivedAccount);
                afterSale.setWxRefundAcceptanceTime(createTime);
                afterSale.setWxRefundStatus(status);
                this.updateSkiAfterSale(afterSale);
            }else {
                throw new ServiceException(orderStr,statusCode);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}
